<template>
  <!-- 只渲染 el-tree-select -->
  <el-tree-select
    v-bind="$attrs"
    v-model="selectedValue"
    :data="options"
    :props="treeSelectProps"
    :loading="isLoading"
    @change="handleTreeSelectChange"
  >
  </el-tree-select>
</template>
<script setup>
//  <ra-dict-tree
//   v-model="formData.formTreeMultiple"
//   code="usr_dept_tree_options"
//   check-strictly
//   show-checkbox
//   default-expand-all
//   multiple
// />
import { ref, watch, computed, nextTick } from 'vue';
import { useDictStore } from '@/store';
// 显式导入 ElTreeSelect
import { ElTreeSelect } from 'element-plus';

const props = defineProps({
  code: {
    type: String,
    required: true,
  },
  perms: {
    type: Boolean,
    default: false,
  },
  modelValue: {
    // For v-model support
    // el-tree-select 可以是单选（String, Number）或多选（Array）
    type: [String, Number, Array, Boolean, Object], // 保持通用性，但通常是 String, Number, Array
    default: null,
  },
  // el-tree-select 特有 props，用于映射数据字段
  treeSelectProps: {
    type: Object,
    default: () => ({
      label: 'label', // 对应 options 里的 label
      value: 'value', // 对应 options 里的 value
      children: 'children', // 对应 options 里的 children
    }),
  },
});

const emit = defineEmits(['update:modelValue', 'change']);

const dictStore = useDictStore();
const options = ref([]);
const isLoading = ref(false);
const dataLoaded = ref(false);

// 计算属性：始终返回 modelValue
const selectedValue = computed({
  get() {
    return props.modelValue;
  },
  set(value) {
    emit('update:modelValue', value);
  },
});

const fetchDictionaryData = async () => {
  if (!props.code) return;

  isLoading.value = true;
  dataLoaded.value = false;

  try {
    const data = await dictStore.getDictionary(props.code, props.perms);
    options.value = data.map((item) => {
      const rawItemValue = item.value !== undefined ? item.value : item.id;
      let finalItemValue = rawItemValue;

      // 尝试根据 modelValue 的类型进行适配
      if (props.modelValue !== null && props.modelValue !== undefined) {
        let targetValueType;
        if (Array.isArray(props.modelValue) && props.modelValue.length > 0) {
          // 如果 modelValue 是数组（多选），取第一个元素的类型作为目标类型
          targetValueType = typeof props.modelValue[0];
        } else if (!Array.isArray(props.modelValue)) {
          // 如果 modelValue 是单个值（单选），取其类型作为目标类型
          targetValueType = typeof props.modelValue;
        }

        // 进行类型转换
        if (
          targetValueType === 'number' &&
          typeof rawItemValue === 'string' &&
          !isNaN(Number(rawItemValue))
        ) {
          finalItemValue = Number(rawItemValue);
        } else if (
          targetValueType === 'string' &&
          typeof rawItemValue === 'number'
        ) {
          finalItemValue = String(rawItemValue);
        }
        // 其他情况（如两者类型一致，或无法进行有效转换）则保持原样
      }

      // 确保返回的数据结构包含 children，以支持树形结构
      return {
        label: item.label || item.name,
        value: finalItemValue,
        children: item.children || undefined, // 保留 children 字段，如果字典数据中存在
      };
    });

    // 数据加载完成
    dataLoaded.value = true;

    // 确保在下一个tick中更新选中值，让组件能够正确回显
    await nextTick();
  } catch (error) {
    console.error('Failed to fetch dictionary data:', error);
    options.value = [];
    dataLoaded.value = true; // 即使出错也标记为已加载
  } finally {
    isLoading.value = false;
  }
};

// 监听 code 和 perms 变化，重新获取数据
watch([() => props.code, () => props.perms], fetchDictionaryData, {
  immediate: true,
});

// 修改后的 change 事件处理函数
const handleTreeSelectChange = async (val, ...rest) => {
  // console.log('el-tree-select change event received:', val, rest);

  // 核心问题是 'val' 是一个 Event 对象。
  // 我们需要 el-tree-select 应该设置到 v-model 的实际值。
  // 由于 v-model 是双向绑定，selectedValue 计算属性的 setter 应该已经被 el-tree-select 调用并传入了正确的值。
  // 我们等待下一个 tick，以确保 v-model 的更新已经传播完成。
  await nextTick();

  // 现在，selectedValue.value 应该持有 el-tree-select 更新后的正确值。
  const actualValue = selectedValue.value;
  // console.log('Value after nextTick (from v-model):', actualValue);

  // 将正确的值通过 'change' 事件向上抛出。
  // 注意：'update:modelValue' 已经在 selectedValue 的 setter 中被 emit 了，这里无需重复 emit。
  emit('change', actualValue);
};

// 暴露一些有用的方法和属性
defineExpose({
  options,
  isLoading,
  dataLoaded,
  refresh: fetchDictionaryData,
});
</script>

<style scoped>
/* Add any specific styles for RaDictSelect here if needed */
</style>
